import FileTree
import os
import FiletreeCompare
import shutil

class ProjectManager(FiletreeCompare.FiletreeCompare):
    # old_file_paths = []
    # new_file_paths = []
    # old_file_tree = FileTree.FileTree()
    # new_file_tree = FileTree.FileTree()
    project_dir = ""

    def __init__(self, _dir=None):
        if dir is None:
            self.project_dir = os.getenv('HOME') + "/zhangli_sync_dir"
        else:
            self.project_dir = _dir
        pass

    def change_dir(self, _dir):
        self.project_dir = _dir

    def __save_files(self):
        all_leaf_nodes = self.diff_file_tree.get_leaf_nodes()
        # >  file to dir
        # <  dir to file
        # - del
        # + add
        # * changed

        add_dir = self.project_dir + "/" + "add_a_"
        changed_dir = self.project_dir + "/" + "changed_a_"

        # if not os.path.exists(add_dir):
        #     os.mkdir(add_dir)
        # if not os.path.exists(changed_dir):
        #     os.mkdir(changed_dir)

        def get_the_dir_root(_path="", _paths=[]):
            i = 0
            for p in _paths:
                if _path.startswith(p):
                    return p,i
                i += 1
            return ""

        def copy_one(src_path, dest_path):
            if os.path.isdir(src_path):
                shutil.copytree(src_path, dest_path)
            else:
                if os.path.exists(os.path.dirname(dest_path)) is False:
                    os.makedirs(os.path.dirname(dest_path))
                shutil.copy(src_path, dest_path)
            pass

        for one_node in all_leaf_nodes:
            one_path = one_node.get_full_path()
            one_flag = one_node.get_data()
            root_dir, i = get_the_dir_root(one_path, self.new_file_paths)
            assert root_dir != ""

            #list_box_compare_result.insert(END, n[1] + "   " + n[0])
            if one_flag == "+":
                add_path = add_dir + str(i) + one_path[len(root_dir):]
                copy_one(one_path, add_path)
                pass
            elif one_flag == "*":
                changed_path = changed_dir + str(i) + one_path[len(root_dir):]
                copy_one(one_path, changed_path)
                pass
            pass
        pass

    @staticmethod
    def __save(_name="", _paths=[], _file_tree=FileTree.FileTree()):
        ret = _file_tree.dump()
        f = open(_name, "w",encoding="utf-8")
        f.write("[Paths " + str(len(_paths)) + "]\n")
        for _dir in _paths:
            f.write(_dir + "\n")
        f.write("[ScanResult " + str(1) + "]\n")
        f.write(ret)
        f.close()
        pass

    def save(self):
        os.mkdir(self.project_dir)
        self.__save(self.project_dir + "/" + "a.zsync", self.old_file_paths, self.old_file_tree)
        self.__save(self.project_dir + "/" + "b.zsync", self.new_file_paths, self.new_file_tree)
        self.__save_files()
        pass

    @staticmethod
    def __load(_name=""):
        f = open(_name, "r",encoding="UTF-8")
        paths_section = f.readline()
        assert paths_section.startswith("[Paths ")
        # consider the end with "/r/n" in Windows or "/n" in Linux
        paths_count = int(paths_section[7:].strip()[:-1])

        file_paths = []
        for i in range(0, paths_count):
            path = f.readline()
            file_paths.append(path.strip())
        scan_result_section = f.readline()
        assert scan_result_section.startswith("[ScanResult ")
        zsync_str = ""
        while True:
            line = f.readline()
            if line == "":
                break
            zsync_str += line
        f.close()
        filetree = FileTree.FileTree()
        filetree.load(zsync_str)
        return file_paths,filetree
        pass

    def load(self):

        self.old_file_paths, self.old_file_tree = self.__load(self.project_dir + "/" + "a.zsync")
        self.new_file_paths, self.new_file_tree = self.__load(self.project_dir + "/" + "b.zsync")
        pass

    def switch(self):
        paths = self.old_file_paths
        ft = self.old_file_tree

        self.old_file_paths = self.new_file_paths
        self.old_file_tree = self.new_file_tree

        self.new_file_paths = paths
        self.new_file_tree = ft

        pass

    def del_file_from_new_and_diff_filetree(self, path):
        _node = self.new_file_tree.get_node(path)
        if _node is None:
            return
        if _node.is_dir() is True:
            shutil.rmtree(path)
        else:
            os.remove(path)
        self.new_file_tree.del_node(path)
        #FIXME: diff tree should delete if child node is empty, otherwise
        #it will show error diff list in UI
        self.diff_file_tree.del_node(path)
